﻿using System;
using System.Collections.Generic;
using System.Text;
using Gammar.Digger.Entity;
using Gammar.Digger.IDAL;
using Gammar.Digger.DALFactory;
using Gammar.Digger.SystemFramework;
using System.Threading;
using System.Data;
namespace Gammar.Digger.BLL
{
    public class PluginsService
    {

        enum Command
        {
            help,

            /// <summary>
            /// 列出所有插件
            /// </summary>
            list,

            /// <summary>
            /// 执行命令
            /// </summary>
            exec,

        }

        enum Scope
        {
            /// <summary>
            /// 全部
            /// </summary>
            all,

            /// <summary>
            /// 指定分类
            /// </summary>
            category,

            /// <summary>
            /// 网站分类
            /// </summary>
            website,

            /// <summary>
            /// 插件(1,2,3...N)
            /// </summary>
            plugin
        }

        private string _isEnableThread = ConfigUtility.GetAppSetting("IsEnableThread");

        /// <summary>
        /// 服务运行状态
        /// </summary>
        public enum Status
        {
            Running,
            Pausing,
            Stopped,
        }
        /// <summary>
        /// 从数据库获取所有可运行插件
        /// </summary>
        /// <returns></returns>
        private SortList<digger_pluginEntity> GetValidPlugins()
        {
            Idigger_plugin IPlugin = DataAccess.Createdigger_plugin();
            SortList<digger_pluginEntity> plugins = IPlugin.GetList("run_status!=1 and is_valid=1");//不等于已经采集，is_valid：有效

            return plugins;
        }

        private void CountWebSite(digger_pluginEntity plugin)
        { 
            
        }

        private web_siteEntity FindWebByName(SortList<web_siteEntity> websites,string name)
        {
            foreach (web_siteEntity entity in websites)
            {
                if (entity.name.Equals(name))
                {
                    return entity;
                }
            }
            return null;
        }

        public void Run()
        {
            LogUtility.WriteAccessLog(string.Format("********采集开始于{0}********", DateTime.Now));

            //获取有效插件
            SortList<digger_pluginEntity> plugins = GetValidPlugins();

            //获取插件分类
            DataTable dtCategory= WebSiteManagement.GetWebSiteChildCategory();

            //获取网站
            SortList<web_siteEntity> dtWebsite=WebSiteManagement.GetAllWebSite();

            //分类的有效插件
            SortList<digger_pluginEntity> pluginsPart = new SortList<digger_pluginEntity>();

                
            string input = string.Empty;

            bool isContinue = false;
       
            while (!isContinue)
            {
                bool isRightCommand = false;
                input = Console.ReadLine();

                string[] inputs = input.Split(' ');
                switch (inputs[0])
                {
                    case "":
                        Console.WriteLine("请输入命令，查看帮助请输入help...");
                        isRightCommand = true;
                        break;
                    case "help":
                        Console.WriteLine("输入格式：命令 范围 分类名称");

                        Console.WriteLine("命令");
                        foreach (string c in Enum.GetNames(typeof(Command)))
                        {
                            Console.WriteLine(c);
                        }
                        Console.WriteLine("---------------------------");
                        Console.WriteLine("范围");
                        foreach (string c in Enum.GetNames(typeof(Scope)))
                        {
                            Console.WriteLine(c);
                        }
                        Console.WriteLine("---------------------------");
                        isRightCommand = true;
                        break;
                    case "clear":
                        Console.Clear();
                        isRightCommand = true;
                        break;
                    case "list":
                        if (inputs.Length==2)
                        {
                            if (inputs[1].Equals(Scope.all.ToString().ToLower()))
                            {
                                foreach (digger_pluginEntity p in plugins)
                                {
                                    Console.WriteLine("{0}{1}{2}{3}{4}",p.plugin_id.Value,"---",p.name,"---",p.category_id.ToString());
                                }
                                isRightCommand = true;
                            }

                        }
                        else if (inputs.Length==3)
                        {
                            if (inputs[1].Equals(Scope.category.ToString().ToLower()))
                            {
                                if (!string.IsNullOrEmpty(inputs[2]))
                                {
                                    DataRow[] rCategory = dtCategory.Select(string.Format("cclass_name='{0}'", inputs[2]));

                                    if (rCategory.Length == 1)
                                    {
                                        foreach (digger_pluginEntity p in plugins)
                                        {
                                            if (p.category_id.ToString() == rCategory[0]["cclass_id"].ToString())
                                            {
                                                Console.WriteLine("{0}{1}{2}{3}{4}", p.plugin_id.Value, "---", p.name, "---", p.category_id.ToString());
                                            }

                                        }
                                      
                                        isRightCommand = true;

                                    }
                                }
                            }

                            if (inputs[1].Equals(Scope.website.ToString().ToLower()))
                            {
                                if (!string.IsNullOrEmpty(inputs[2]))
                                {
                                    web_siteEntity site = FindWebByName(dtWebsite, inputs[2]);
                                    if (site != null)
                                    {
                                        foreach (digger_pluginEntity p in plugins)
                                        {
                                            if (p.site_id.Value == site.site_id.Value)
                                            {
                                                Console.WriteLine("{0}{1}{2}{3}{4}", p.plugin_id.Value, "---", p.name, "---", p.category_id.ToString());
                                            }

                                        }
                                        isRightCommand = true;
                                    }
                                }
                            }

                            if (inputs[1].Equals(Scope.plugin.ToString().ToLower()))
                            {
                                if (!string.IsNullOrEmpty(inputs[2]))
                                {
                                    string[] strPlugins = inputs[2].Split(',');

                                    foreach (digger_pluginEntity p in plugins)
                                    {
                                        foreach (string s in strPlugins)
                                        {
                                            if (s == p.plugin_id.ToString())
                                            {
                                                Console.WriteLine("{0}{1}{2}{3}{4}", p.plugin_id.Value, "---", p.name, "---", p.category_id.ToString());
                                               // pluginsPart.Add(p);
                                                break;
                                            }
                                        }
                                    }
                                   
                                    isRightCommand = true;
  
                                }
                            }
                        }

                        break;
                    case "exec":
                        if (inputs.Length == 2)
                        {
                            if (inputs[1].Equals(Scope.all.ToString().ToLower()))
                            {
                                foreach (digger_pluginEntity p in plugins)
                                {
                                    Console.WriteLine("{0}{1}{2}{3}{4}", p.plugin_id.Value, "---", p.name, "---", p.category_id.ToString());
                                }
                                isRightCommand = true;
                                isContinue = true;
                            }

                        }
                        else if (inputs.Length == 3)
                        {
                            if (inputs[1].Equals(Scope.category.ToString().ToLower()))
                            {
                                if (!string.IsNullOrEmpty(inputs[2]))
                                {
                                    DataRow[] rCategory = dtCategory.Select(string.Format("cclass_name='{0}'", inputs[2]));

                                    if (rCategory.Length == 1)
                                    {
                                        foreach (digger_pluginEntity p in plugins)
                                        {
                                            if (p.category_id.ToString() == rCategory[0]["cclass_id"].ToString())
                                            {
                                                Console.WriteLine("{0}{1}{2}{3}{4}", p.plugin_id.Value, "---", p.name, "---", p.category_id.ToString());
                                                pluginsPart.Add(p);
                                            }

                                        }
                                        plugins = pluginsPart;
                                        isRightCommand = true;
                                        isContinue = true;
                                    }
                                }
                            }
                            if (inputs[1].Equals(Scope.website.ToString().ToLower()))
                            {
                                if (!string.IsNullOrEmpty(inputs[2]))
                                {
                                    web_siteEntity site = FindWebByName(dtWebsite, inputs[2]);
                                    if (site != null)
                                    {
                                        foreach (digger_pluginEntity p in plugins)
                                        {
                                            if (p.site_id.Value == site.site_id.Value)
                                            {
                                                Console.WriteLine("{0}{1}{2}{3}{4}", p.plugin_id.Value, "---", p.name, "---", p.category_id.ToString());
                                                pluginsPart.Add(p);
                                            }

                                        }
                                        plugins = pluginsPart;
                                        isRightCommand = true;
                                        isContinue = true;
                                    }
                                }
                            }

                            if (inputs[1].Equals(Scope.plugin.ToString().ToLower()))
                            {
                                if (!string.IsNullOrEmpty(inputs[2]))
                                {
                                    string[] strPlugins = inputs[2].Split(',');

                                    foreach (digger_pluginEntity p in plugins)
                                    {
                                        foreach (string s in strPlugins)
                                        {
                                            if (s==p.plugin_id.ToString())
                                            {
                                                Console.WriteLine("{0}{1}{2}{3}{4}", p.plugin_id.Value, "---", p.name, "---", p.category_id.ToString());
                                                pluginsPart.Add(p);
                                                break;
                                            }
                                        }
                                    }
                                    plugins = pluginsPart;
                                    isRightCommand = true;
                                    isContinue = true;
                                }
                            }

                        }
                        break;
                    default:
                        break;
                }
                if (!isRightCommand)
                {
                    Console.WriteLine("命令格式不正确请重新输入...");
                }

                if (isContinue)
                {
                    Console.WriteLine("命令正确，开始进行采集...");
                    break;
                }
              
            }


           


           //执行命令操作
            
            //写入运行日志
            ISystem_status systemStatus = DataAccess.CreateSystem_status();
            System_statusEntity systemStatusEntity = new System_statusEntity();
            systemStatusEntity.start_time = DateTime.Now.Ticks;
            systemStatusEntity.status = (int)Status.Running;
            systemStatusEntity.sum_plugins = plugins.Count;

            int primaryKey = systemStatus.AddPartial(systemStatusEntity);

            Console.WriteLine("本次采集执行插件总数:{0}", plugins.Count);

            plugin_run_statusEntity entity;
            Iplugin_run_status run_status = DataAccess.Createplugin_run_status();

            Dictionary<int, int> statusKeys = new Dictionary<int, int>();
            foreach (digger_pluginEntity plugin in plugins)
            {
                entity = new plugin_run_statusEntity();
                entity.plugin_id = plugin.plugin_id.Value;
                entity.sys_id = primaryKey;
                int key= run_status.AddPartial(entity);
                statusKeys.Add(plugin.plugin_id.Value, key);
            }
            
            //foreach (digger_pluginEntity plugin in plugins)
            //{
            //    DataCollectService dc = new DataCollectService(plugin);
            //    Thread t = new Thread(new ThreadStart(dc.Collect));
            //    t.Start();
            //    Console.WriteLine("正在采集：{0}---{1}", plugin.plugin_id, plugin.name);
            //}

            if (_isEnableThread=="1")
            {
                Thread[] threads = new Thread[plugins.Count];
                for (int i = 0; i < plugins.Count; i++)
                {
                    DataCollectService dc = new DataCollectService(plugins[i], primaryKey, statusKeys[plugins[i].plugin_id.Value]);
                    threads[i] = new Thread(new ThreadStart(dc.Collect));
                    threads[i].Start();
                    Console.WriteLine("正在采集：{0}---{1}", plugins[i].plugin_id, plugins[i].name);
                }

                for (int i = 0; i < plugins.Count; i++)
                {
                    if (!threads[i].IsAlive)
                    {
                        Console.WriteLine(threads[i].Name + "ABORT！");
                        threads[i].Abort();
                    }
                }
            }
            else
            {
                for (int i = 0; i < plugins.Count; i++)
                {
                    DataCollectService dc = new DataCollectService(plugins[i], primaryKey, statusKeys[plugins[i].plugin_id.Value]);
                    dc.Collect();

                    Console.WriteLine("采集插件"+i+"    运行结束");
                }
            }
            
            //更新运行日志，结束时间和状态
            System_statusEntity sysentity=new System_statusEntity();
            sysentity.end_time = DateTime.Now.Ticks;
            sysentity.status = (int)Status.Stopped;
            systemStatus.Updatepartial(sysentity, "sys_id=" + primaryKey.ToString());
        
        }
    

    }
}
